Resizegrad
计算 Resize 操作的梯度。该算子包含两种实现:最近邻插值梯度(ResizeNearestNeighborGrad)和双线性插值梯度(ResizeBiLinearGrad)。用于将上游梯度从输出尺寸反向传播到输入尺寸。
最近邻插值梯度(ResizeNearestNeighborGrad)
对于最近邻插值,输入梯度通过最近邻映射反向传播到输出梯度。
其中 in_addr 是上游梯度(输出尺寸),out_addr 是输入梯度(输入尺寸)。注意使用累加操作(+=),因为多个输入位置可能映射到同一个输出位置。
双线性插值梯度(ResizeBiLinearGrad)
对于双线性插值,输入梯度通过双线性插值的反向传播分配到4个相邻的输出位置。
对于 x 维度有类似的公式:
输入梯度按权重分配到4个相邻位置:
- 输入:
in_addr - 指向上游梯度数据的指针(输出尺寸的梯度)。
out_addr - 指向输出梯度数据的指针(输入尺寸的梯度),需要初始化为0。
batch_size - 批次大小。
channel - 通道数。
format - 数据格式,0 表示 NHWC,1 表示 NCHW。
align_corners - 是否对齐角点标志,0 表示不对齐,1 表示对齐。
in_height - 输入高度。
in_width - 输入宽度。
out_height - 输出高度。
out_width - 输出宽度。
height_scale - 高度缩放因子,通常为 (out_height - 1) / (in_height - 1) 或 out_height / in_height。
width_scale - 宽度缩放因子,通常为 (out_width - 1) / (in_width - 1) 或 out_width / in_width。
- 输出:
out_addr - 计算后的输入梯度(输入尺寸的梯度)。
- 支持平台:
FT78NEMT7004
备注
FT78NE 支持 fp32
MT7004 支持 fp16, fp32
共享存储版本:
-
void fp_resizenearestneighborgrad_s(float *in_addr, float *out_addr, int batch_size, int channel, int format, int align_corners, int in_height, int in_width, int out_height, int out_width, float height_scale, float width_scale, int core_mask)
-
void hp_resizenearestneighborgrad_s(half *in_addr, half *out_addr, int batch_size, int channel, int format, int align_corners, int in_height, int in_width, int out_height, int out_width, float height_scale, float width_scale, int core_mask)
-
void fp_resizebilineargrad_s(float *in_addr, float *out_addr, int batch_size, int channel, int format, int align_corners, int in_height, int in_width, int out_height, int out_width, float height_scale, float width_scale, int core_mask)
-
void hp_resizebilineargrad_s(half *in_addr, half *out_addr, int batch_size, int channel, int format, int align_corners, int in_height, int in_width, int out_height, int out_width, float height_scale, float width_scale, int core_mask)
C调用示例(最近邻插值梯度):
1#include <stdio.h>
2#include <resizegrad.h>
3
4int main(int argc, char* argv[]) {
5 float *in_addr = (float *)0x10010000;
6 float *out_addr = (float *)0x10020000;
7
8 int batch_size = 4;
9 int channel = 3;
10 int format = 1;
11 int align_corners = 1;
12 int in_height = 4, in_width = 4;
13 int out_height = 6, out_width = 6;
14 int core_mask = 0xff;
15
16 float height_scale = (float)(out_height - 1) / (in_height - 1);
17 float width_scale = (float)(out_width - 1) / (in_width - 1);
18
19 int output_size = in_height * in_width * channel * batch_size;
20 memset(out_addr, 0, output_size * sizeof(float));
21
22 fp_resizenearestneighborgrad_s(in_addr, out_addr, batch_size, channel,
23 format, align_corners, in_height, in_width,
24 out_height, out_width, height_scale, width_scale, core_mask);
25 return 0;
26}
私有存储版本:
-
void fp_resizenearestneighborgrad_p(float *in_addr, float *out_addr, int batch_size, int channel, int format, int align_corners, int in_height, int in_width, int out_height, int out_width, float height_scale, float width_scale)
-
void hp_resizenearestneighborgrad_p(half *in_addr, half *out_addr, int batch_size, int channel, int format, int align_corners, int in_height, int in_width, int out_height, int out_width, float height_scale, float width_scale)
-
void fp_resizebilineargrad_p(float *in_addr, float *out_addr, int batch_size, int channel, int format, int align_corners, int in_height, int in_width, int out_height, int out_width, float height_scale, float width_scale)
-
void hp_resizebilineargrad_p(half *in_addr, half *out_addr, int batch_size, int channel, int format, int align_corners, int in_height, int in_width, int out_height, int out_width, float height_scale, float width_scale)
C调用示例(双线性插值梯度):
1#include <stdio.h>
2#include <resizegrad.h>
3
4int main(int argc, char* argv[]) {
5 float *in_addr = (float *)0x10010000;
6 float *out_addr = (float *)0x10020000;
7
8 int batch_size = 4;
9 int channel = 3;
10 int format = 0;
11 int align_corners = 0;
12 int in_height = 4, in_width = 4;
13 int out_height = 6, out_width = 6;
14
15 float height_scale = (float)out_height / in_height;
16 float width_scale = (float)out_width / in_width;
17
18 int output_size = in_height * in_width * channel * batch_size;
19 memset(out_addr, 0, output_size * sizeof(float));
20
21 fp_resizebilineargrad_p(in_addr, out_addr, batch_size, channel,
22 format, align_corners, in_height, in_width,
23 out_height, out_width, height_scale, width_scale);
24 return 0;
25}